/**
 * GarinDriver -- Eclipse Public License - v 1.0
 * http://www.eclipse.org/legal/epl-v10.html
 */
package garin.parse.io;

import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * Char source for the parser framework
 * 
 * @author Mark Farnsworth
 */
public final class FileSource extends AbstractSource implements Closeable {
	private char ch;
	final RandomAccessFile in;
	private long at = -1;
	
	public FileSource(final File file) throws FileNotFoundException {
		in = new RandomAccessFile(file, "r");
	}
	
	public final long at() {
		return at;
	}
	
	public final char ch() {
		return ch;
	}
	
	public void close() throws IOException {
		in.close();
	}
	
	public final String contents(final long start, long end) throws IOException {
		in.seek(start);
		final long len = in.length();
		end = end <= len ? end : len;
		final int sz = (int) (end - start);
		if (sz < 1) return null;
		final byte[] b = new byte[sz];
		in.readFully(b);
		return new String(b);
	}
	
	/**
	 * @return true if we were able to read a char
	 * @throws IOException
	 */
	public final boolean go() throws IOException {
		at++;
		in.seek(at);
		final int read = in.read();
		ch = (char) read;
		if (read != -1) return true;
		return false;
	}
	
	public boolean go(final long pos) throws IOException {
		at = pos - 1;
		return go();
	}
}
